package com.zhupf.queue;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

/**
 * @author zhupf
 * @date 2024年12月25日 10:29
 * @Description 1438. 绝对差不超过限制的最长连续子数组
 * https://leetcode.cn/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit/description/
 * 给你一个整数数组 nums ，和一个表示限制的整数 limit，请你返回最长连续子数组的长度，该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。
 * <p>
 * 如果不存在满足条件的子数组，则返回 0 。
 * 示例 2：
 * <p>
 * 输入：nums = [10,1,2,4,7,2], limit = 5
 * 输出：4
 * 解释：满足题意的最长子数组是 [2,4,7,2]，其最大绝对差 |2-7| = 5 <= 5 。
 * 示例 3：
 * <p>
 * 输入：nums = [4,2,2,2,4,4,2,2], limit = 0
 * 输出：3
 */
public class LongestSubarray {
    public static void main(String[] args) {
        int[] nums = {10,1,2,4,7,2};
        System.out.println(longestSubarray(nums, 5));
    }

    public static int longestSubarray(int[] nums, int limit) {
        Deque<Integer> maxQueue = new LinkedList<>();
        Deque<Integer> minQueue = new LinkedList<>();
        int l = 0;
        int r = 0;
        int ret = 0;
        while (r < nums.length) {
            while (!maxQueue.isEmpty() && nums[maxQueue.peekLast()] < nums[r]) {
                maxQueue.pollLast();
            }
            while (!minQueue.isEmpty() && nums[minQueue.peekLast()] > nums[r]) {
                minQueue.pollLast();
            }
            maxQueue.offerLast(r);
            minQueue.offerLast(r);
            while (!minQueue.isEmpty() && !maxQueue.isEmpty() && (nums[maxQueue.peekFirst()] - nums[minQueue.peekFirst()]) > limit) {
                if (maxQueue.peekFirst() == l) {
                    maxQueue.pollFirst();
                }
                if (minQueue.peekFirst() == l) {
                    minQueue.pollFirst();
                }
                l++;
            }
            ret = Math.max(ret, r - l + 1);
            r++;
        }
        return ret;
    }

}
